require 'uri'
require 'goliath'
require 'em-synchrony/em-http'
require 'em-http/middleware/json_response'
require 'redis'
require 'redis/connection/synchrony'

require './lib/canonizer.rb'

EM::HttpRequest.use EventMachine::Middleware::JSONResponse

class RedisCache
  def redis
    @redis_instance ||= if ENV['REDISTOGO_URL']
      uri = URI.parse ENV['REDISTOGO_URL']
      Redis.new host: uri.host, port: uri.port, password: uri.password
    else
      Redis.new
    end
  end

  def duration
    # default cache duration fallback
    ENV['POPE_CACHE_DURATION'] ||  5 * 60
  end

  def store(key, &block)
    key = "result:url:#{key}"

    cached_result = redis.get(key)

    if cached_result
      eval cached_result
    else
      block.call.tap { |result| redis.setex(key, duration, result) }
    end
  end
end

class Pope < Goliath::API
  use Goliath::Rack::Params
  use Goliath::Rack::JSONP
  use Goliath::Rack::Formatters::JSON
  use Goliath::Rack::Validation::RequestMethod, ['GET']
  use Goliath::Rack::Validation::RequiredParam, { key: 'url' }

  def cache
    @cache ||= RedisCache.new
  end

  def response(env)
    url = params['url']

    result = cache.store(url) do
      Canonizer.perform(url)
    end

    status_code = result[:error] ? 500 : 200
    [status_code, { 'Content-Type' => 'application/javascript' }, result]
  end
end
